package com.zboin.framework.serve;

import java.util.Map;
import java.util.concurrent.*;

/**
 * 自定义简单定时任务器
 */
public class ScheduleServe {

    private final Map<String, ScheduledFuture<?>> scheduledTasks = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler;

    private ScheduleServe() {
        scheduler = new ScheduledThreadPoolExecutor(1);
    }

    private static final class InstanceHolder {
        private static ScheduleServe INSTANCE = null;
    }

    public static ScheduleServe getInstance() {
        ScheduleServe service = InstanceHolder.INSTANCE;
        if (service == null) {
            synchronized (ScheduleServe.class) {
                service = InstanceHolder.INSTANCE;
                if (service == null) {
                    InstanceHolder.INSTANCE  = new ScheduleServe();
                    service = InstanceHolder.INSTANCE;
                }
            }
        }
        return service;
    }

    /**
     * 添加固定延迟执行的任务
     * @param taskId 任务ID
     * @param task 要执行的任务
     * @param initialDelay 初始延迟时间
     * @param delay 每次执行之间的延迟
     * @param unit 时间单位
     * @return 任务是否添加成功
     */
    public boolean scheduleWithFixedDelay(String taskId, Runnable task,
                                          long initialDelay, long delay, TimeUnit unit) {
        if (scheduledTasks.containsKey(taskId)) {
            return false; // 任务ID已存在
        }

        ScheduledFuture<?> future = scheduler.scheduleWithFixedDelay(
                task, initialDelay, delay, unit);

        scheduledTasks.put(taskId, future);
        return true;
    }

    /**
     * 添加固定频率执行的任务
     * @param taskId 任务ID
     * @param task 要执行的任务
     * @param initialDelay 初始延迟时间
     * @param period 执行周期
     * @param unit 时间单位
     * @return 任务是否添加成功
     */
    public boolean scheduleAtFixedRate(String taskId, Runnable task,
                                       long initialDelay, long period, TimeUnit unit) {
        if (scheduledTasks.containsKey(taskId)) {
            return false; // 任务ID已存在
        }

        ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(
                task, initialDelay, period, unit);

        scheduledTasks.put(taskId, future);
        return true;
    }

    /**
     * 添加延迟执行的一次性任务
     * @param taskId 任务ID
     * @param task 要执行的任务
     * @param delay 延迟时间
     * @param unit 时间单位
     * @return 任务是否添加成功
     */
    public boolean scheduleOnce(String taskId, Runnable task,
                                long delay, TimeUnit unit) {
        if (scheduledTasks.containsKey(taskId)) {
            return false; // 任务ID已存在
        }

        ScheduledFuture<?> future = scheduler.schedule(task, delay, unit);

        // 一次性任务执行后自动移除
        CompletableFuture.runAsync(() -> {
            try {
                future.get(); // 等待任务完成
                scheduledTasks.remove(taskId);
            } catch (Exception e) {
                // 处理异常
                scheduledTasks.remove(taskId);
            }
        });

        scheduledTasks.put(taskId, future);
        return true;
    }

    /**
     * 取消并移除任务
     * @param taskId 任务ID
     * @param mayInterruptIfRunning 是否中断正在执行的任务
     * @return 任务是否成功移除
     */
    public boolean cancelTask(String taskId, boolean mayInterruptIfRunning) {
        ScheduledFuture<?> future = scheduledTasks.get(taskId);
        if (future == null) {
            return false; // 任务不存在
        }

        boolean cancelled = future.cancel(mayInterruptIfRunning);
        if (cancelled) {
            scheduledTasks.remove(taskId);
        }
        return cancelled;
    }

    /**
     * 检查任务是否存在
     * @param taskId 任务ID
     * @return 任务是否存在
     */
    public boolean containsTask(String taskId) {
        return scheduledTasks.containsKey(taskId);
    }

    /**
     * 关闭任务调度器
     * @param awaitTermination 是否等待任务完成
     * @param timeout 等待时间
     * @param unit 时间单位
     */
    public void shutdown(boolean awaitTermination, long timeout, TimeUnit unit) {
        scheduler.shutdown();

        if (awaitTermination) {
            try {
                scheduler.awaitTermination(timeout, unit);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }

        scheduledTasks.clear();
    }

    /**
     * 获取任务数量
     * @return 当前任务数量
     */
    public int getTaskCount() {
        return scheduledTasks.size();
    }
}
